package org.springblade.tms.module.inquirysheet.base;

import com.mpobjects.bdparsii.eval.Expression;
import com.mpobjects.bdparsii.eval.Parser;
import com.mpobjects.bdparsii.eval.Scope;
import com.mpobjects.bdparsii.eval.Variable;
import lombok.SneakyThrows;
import org.apache.logging.log4j.util.Strings;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.tms.global.enums.EnquiryTypeEnum;
import org.springblade.tms.global.enums.UserTypeEnum;
import org.springblade.tms.module.currencytype.entity.TMCurrencyType;
import org.springblade.tms.module.currencytype.service.ICurrencyTypeService;
import org.springblade.tms.module.historicalquotation.entity.TMHistoricalQuotation;
import org.springblade.tms.module.historicalquotation.service.IHistoricalQuotationService;
import org.springblade.tms.module.inquirycarrier.entity.TMInquiryCarrier;
import org.springblade.tms.module.inquirycarrier.service.IInquiryCarrierService;
import org.springblade.tms.module.inquirysheet.entity.TMInquirySheet;
import org.springblade.tms.module.inquirysheet.service.IInquirySheetService;
import org.springblade.tms.module.inquirysheet.vo.HistoricalQuotationVO;
import org.springblade.tms.module.inquirysheet.vo.InquiryItemQueryVo;
import org.springblade.tms.module.inquirysheet.vo.ViewRankingRespVO;
import org.springblade.tms.module.inquirysheet.vo.ViewRankingVO;
import org.springblade.tms.module.offer.entity.TMOffer;
import org.springblade.tms.module.offer.service.IOfferService;
import org.springblade.tms.module.userinfo.entity.TMUserInfo;
import org.springblade.tms.module.userinfo.service.IUserInfoService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @projectName: BladeX
 * @package: org.springblade.tms.module.inquirysheet.base
 * @className: InquirySheetAppService
 * @author: yr
 * @description: 询价单小程序服务
 * @date: 2022/6/29 10:42
 */
@Service
public class InquirySheetAppService {
	@Resource
	private IInquirySheetService iInquirySheetService;
	@Resource
	private IUserInfoService userInfoService;
	@Resource
	private IInquiryCarrierService iInquiryCarrierService;
	@Resource
	private IOfferService offerService;
	@Resource
	private ICurrencyTypeService currencyTypeService;
	@Resource
	private IHistoricalQuotationService historicalQuotationService;

	/**
	 * @param id:
	 * @return R<Boolean>
	 * @author yr
	 * @description 承运商小程序报价信息查询
	 * @date 2022/6/27 11:24
	 */
	public R<InquiryItemQueryVo> priceOne(Long id) {
		TMInquiryCarrier tmInquiryCarrier = getInquiryCarrierByUser(id);
		if (tmInquiryCarrier == null) {
			return R.status(true);
		}
		List<TMOffer> tmOffers = offerService.lambdaQuery().eq(TMOffer::getParentId, tmInquiryCarrier.getId()).list();
		HashMap<String, String> offerMap = new HashMap<>();
		tmOffers.forEach(tmOffer -> {
			offerMap.put(tmOffer.getFieldName(), tmOffer.getValue());
		});
		InquiryItemQueryVo copy = BeanUtil.copy(offerMap, InquiryItemQueryVo.class);
		copy.setId(tmInquiryCarrier.getId());
		return R.data(copy);
	}

	/**
	 * @param id:
	 * @return R<HistoricalQuotationVO>
	 * @author yr
	 * @description 小程序议价详情接口
	 * @date 2022/6/29 11:01
	 */
	public R<HistoricalQuotationVO> negotiationDetails(Long id) {
		TMInquiryCarrier tmInquiryCarrier = getInquiryCarrierByUser(id);
		if (tmInquiryCarrier == null) {
			return R.status(true);
		}
		List<TMHistoricalQuotation> tmHistoricalQuotations = historicalQuotationService.lambdaQuery()
			.eq(TMHistoricalQuotation::getParentId, tmInquiryCarrier.getId())
			.eq(TMHistoricalQuotation::getBidder, UserTypeEnum.ADMIN.getDescription())
			.orderByDesc(TMHistoricalQuotation::getCreateTime,TMHistoricalQuotation::getId)
			.list();
		if (tmHistoricalQuotations.isEmpty()) {
			return R.status(true);
		} else {
			return R.data(BeanUtil.copy(tmHistoricalQuotations.get(0), HistoricalQuotationVO.class));
		}
	}

	/**
	 * @param id:
	 * @return TMInquiryCarrier
	 * @author yr
	 * @description 报价详情承运商
	 * @date 2022/6/29 15:42
	 */
	private TMInquiryCarrier getInquiryCarrierByUser(Long id) {
		Long userId = AuthUtil.getUser().getUserId();
		TMUserInfo tmUserInfo = userInfoService.lambdaQuery().eq(TMUserInfo::getParentId, userId).one();
		TMInquiryCarrier tmInquiryCarriers = iInquiryCarrierService.lambdaQuery()
			.eq(TMInquiryCarrier::getParentId, id)
			.eq(TMInquiryCarrier::getCarrierId, tmUserInfo.getTmId())
			.isNull(TMInquiryCarrier::getShippingCompany)
			.one();
		if (tmInquiryCarriers != null) {
			return tmInquiryCarriers;
		}
		return null;
	}

	/**
	 * @param :
	 * @return Object
	 * @author yr
	 * @description app查看排名接口
	 * @date 2022/6/29 15:43
	 */
	@SneakyThrows
	public R<ViewRankingVO> viewRanking(Long id) {
		Long userId = AuthUtil.getUser().getUserId();
		TMUserInfo tmUserInfo = userInfoService.lambdaQuery().eq(TMUserInfo::getParentId, userId).one();
		TMInquirySheet inquirySheet = iInquirySheetService.getById(id);
		List<TMInquiryCarrier> tmInquiryCarriers = iInquiryCarrierService.lambdaQuery()
			.eq(TMInquiryCarrier::getParentId, id)
			.isNull(TMInquiryCarrier::getShippingCompany)
			.list();
		List<Long> inquiryCarrierIds = tmInquiryCarriers.stream().map(TMInquiryCarrier::getId).collect(Collectors.toList());
		List<TMOffer> tmOffers = offerService.lambdaQuery().in(TMOffer::getParentId, inquiryCarrierIds).list();
		Map<Long, List<TMOffer>> offerByParentIdMap = tmOffers.stream().collect(Collectors.groupingBy(TMOffer::getParentId));
		ArrayList<InquiryItemQueryVo> inquiryItemQueryVos = new ArrayList<>();
		if (!inquirySheet.getWorkflowId().equals(EnquiryTypeEnum.foreignTrade.getValue())) {
			tmInquiryCarriers.forEach(tmInquiryCarrier -> {
				List<TMOffer> tmOfferList = offerByParentIdMap.get(tmInquiryCarrier.getId());
				if (tmOfferList == null) {
					return;
				} else {
					HashMap<String, Object> hashMap = new HashMap<>();
					tmOfferList.forEach(tmOffer -> {
						hashMap.put(tmOffer.getFieldName(), tmOffer.getValue());
					});
					InquiryItemQueryVo inquiryItemQueryVo = BeanUtil.copy(hashMap, InquiryItemQueryVo.class);
					inquiryItemQueryVo.setCarrierName(tmInquiryCarrier.getCarrierName());
					inquiryItemQueryVo.setCarrierId(tmInquiryCarrier.getCarrierId());
					if (Strings.isNotBlank(inquiryItemQueryVo.getQuotedPrice())) {
						inquiryItemQueryVo.setFieldsForRanking(BigDecimal.valueOf(Long.parseLong(inquiryItemQueryVo.getQuotedPrice())));
					} else {
						inquiryItemQueryVo.setFieldsForRanking(BigDecimal.valueOf(Long.parseLong(inquiryItemQueryVo.getQuotedPrice1())));
					}
					inquiryItemQueryVos.add(inquiryItemQueryVo);
				}
			});
		} else {
			//外贸排名所需数据
			TMCurrencyType currencyType = currencyTypeService.lambdaQuery().eq(TMCurrencyType::getName, "USD").one();
			BigDecimal typeRate = currencyType.getRate();
			Scope scope = new Scope();
			Variable rate = scope.getVariable("rate");
			Expression expr = Parser.parse("shippingFee * rate + portCharges", scope);
			rate.setValue(typeRate);
			//获取外贸报价详情列表
			List<TMInquiryCarrier> inquiryCarriers = iInquiryCarrierService.lambdaQuery()
				.eq(TMInquiryCarrier::getParentId, id)
				.isNotNull(TMInquiryCarrier::getShippingCompany)
				.list();
			//查询出所有报价信息
			List<Long> inquiryIds = inquiryCarriers.stream().map(TMInquiryCarrier::getId).collect(Collectors.toList());
			List<TMOffer> list = offerService.lambdaQuery().in(TMOffer::getParentId, inquiryIds).list();
			Map<Long, List<TMOffer>> offerByParentId = list.stream().collect(Collectors.groupingBy(TMOffer::getParentId));
			//根据承运商id分组
			Map<String, List<TMInquiryCarrier>> inquiryCarrierListByCarrierId = inquiryCarriers.stream().collect(Collectors.groupingBy(TMInquiryCarrier::getCarrierId));
			inquiryCarrierListByCarrierId.forEach((s, tmInquiryCarrierList) -> {
				ArrayList<InquiryItemQueryVo> inquiryItemQueryVoArrayList = new ArrayList<>();
				inquiryCarrierListByCarrierId.get(s).forEach(tmInquiryCarrier -> {
					HashMap<String, Object> hashMap = new HashMap<>();
					List<TMOffer> offers = offerByParentId.get(tmInquiryCarrier.getId());
					offers.forEach(tmOffer -> {
						hashMap.put(tmOffer.getFieldName(), tmOffer.getValue());
					});
					InquiryItemQueryVo itemQueryVo = BeanUtil.toBean(hashMap, InquiryItemQueryVo.class);
					itemQueryVo.setCarrierId(tmInquiryCarrier.getCarrierId());
					itemQueryVo.setCarrierName(tmInquiryCarrier.getCarrierName());
					inquiryItemQueryVoArrayList.add(itemQueryVo);
				});
				InquiryItemQueryVo itemQueryVo = inquiryItemQueryVoArrayList.stream().min((a, b) -> {
					//根据公式得出值然后得出最小运费
					Variable shippingFee = scope.getVariable("shippingFee");
					shippingFee.setValue(BigDecimal.valueOf(Long.parseLong(a.getShippingFee())));
					Variable portCharges = scope.getVariable("portCharges");
					portCharges.setValue(BigDecimal.valueOf(Long.parseLong(a.getPortCharges())));
					BigDecimal evaluateA = expr.evaluate();
					shippingFee.setValue(BigDecimal.valueOf(Long.parseLong(b.getShippingFee())));
					portCharges.setValue(BigDecimal.valueOf(Long.parseLong(b.getPortCharges())));
					BigDecimal evaluateB = expr.evaluate();
					return evaluateA.compareTo(evaluateB);
				}).get();
				Variable shippingFee = scope.getVariable("shippingFee");
				shippingFee.setValue(BigDecimal.valueOf(Long.parseLong(itemQueryVo.getShippingFee())));
				Variable portCharges = scope.getVariable("portCharges");
				portCharges.setValue(BigDecimal.valueOf(Long.parseLong(itemQueryVo.getPortCharges())));
				BigDecimal evaluate = expr.evaluate();
				itemQueryVo.setFieldsForRanking(evaluate);
				inquiryItemQueryVos.add(itemQueryVo);
			});
		}
		List<InquiryItemQueryVo> itemQueryVos = inquiryItemQueryVos.stream().sorted((o1, o2) -> {
			return o2.getFieldsForRanking().compareTo(o1.getFieldsForRanking());
		}).collect(Collectors.toList());
		AtomicInteger ranking = new AtomicInteger(1);
		ViewRankingVO rankingVO = new ViewRankingVO();
		ArrayList<ViewRankingRespVO> viewRankingRespVOS = new ArrayList<>();
		itemQueryVos.forEach(inquiryItemQueryVo -> {
			ViewRankingRespVO viewRankingVO = new ViewRankingRespVO();
			viewRankingVO.setCarrierName(inquiryItemQueryVo.getCarrierName());
			viewRankingVO.setRanking(ranking.get());
			ranking.getAndIncrement();
			if (tmUserInfo.getTmId().equals(inquiryItemQueryVo.getCarrierId())) {
				rankingVO.setViewRankingVO(viewRankingVO);
			}
			viewRankingRespVOS.add(viewRankingVO);
		});
		rankingVO.setViewRankingRespVOS(viewRankingRespVOS);
		return R.data(rankingVO);
	}

	/**
	 * @param id:
	 * @return R<InquiryItemQueryVo>
	 * @author yr
	 * @description 单个报价详情
	 * @date 2022/6/30 10:10
	 */
	public R<InquiryItemQueryVo> priceDetail(Long id) {
		TMInquiryCarrier tmInquiryCarrier = iInquiryCarrierService.getById(id);
		List<TMOffer> tmOffers = offerService.lambdaQuery().eq(TMOffer::getParentId, tmInquiryCarrier.getId()).list();
		HashMap<String, Object> hashMap = new HashMap<>();
		tmOffers.forEach(tmOffer -> {
			hashMap.put(tmOffer.getFieldName(), tmOffer.getValue());
		});
		InquiryItemQueryVo inquiryItemQueryVo = BeanUtil.copy(hashMap, InquiryItemQueryVo.class);
		inquiryItemQueryVo.setId(id);
		inquiryItemQueryVo.setShippingCompany(tmInquiryCarrier.getShippingCompany());
		return R.data(inquiryItemQueryVo);
	}
}
